package crmdna.common;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Test;

import crmdna.common.APIResponse.Status;

public class UtilsTest {
	@Test
	public void getQSTagsTest() {
		
		//Set<String> qsTags = Utils.getQSTags("sathyanarayanant@gmail.com", 
		//		"sathyanarayanan", "thilakan", "98361844", null, "65227030");
		Set<String> qsTags = Utils.getQSTags("sathyanarayanant@gmail.com", 
				"Sathyanarayanan", "thilakan", null, null);
		
		Set<String> expected = new TreeSet<>();
		expected.add("sat");
		expected.add("ath");
		expected.add("thy");
		expected.add("hya");
		expected.add("yan");
		expected.add("ana");
		expected.add("nar");
		expected.add("ara");
		expected.add("ray");
		expected.add("aya");
		expected.add("yan");
		expected.add("ana");
		expected.add("nan");
		expected.add("ant");
		expected.add("nt@");
		expected.add("t@g");
		expected.add("@gm");
		expected.add("gma");
		expected.add("mai");
		expected.add("ail");
		expected.add("il.");
		expected.add("l.c");
		expected.add(".co");
		expected.add("com");
		
		//thilakan
		expected.add("thi");
		expected.add("hil");
		expected.add("ila");
		expected.add("lak");
		expected.add("aka");
		expected.add("kan");
		
		assertTrue(qsTags.containsAll(expected));
		assertEquals(expected.size(), qsTags.size());				
	}
   
	@Test public void isPresentInListCaseInsensitiveTest() {
		assertEquals(false, Utils.isPresentInListCaseInsensitive(null, null));
		
		assertEquals(false, 
				Utils.isPresentInListCaseInsensitive(new ArrayList<String>(), null));
		
		assertEquals(false, 
				Utils.isPresentInListCaseInsensitive(new ArrayList<String>(), ""));
		
		List<String> list = new ArrayList<String>();
		list.add("sathya");
		list.add("sowmya");
		list.add("balaji");
		
		assertEquals(true, 
				Utils.isPresentInListCaseInsensitive(list, "sAthYa"));
		assertEquals(true, 
				Utils.isPresentInListCaseInsensitive(list, "balaji"));
		assertEquals(true, 
				Utils.isPresentInListCaseInsensitive(list, "SowmYa"));
		
		assertEquals(false, 
				Utils.isPresentInListCaseInsensitive(list, "thilakan"));
						
	}
	
	@Test 
	public void throwIncorrectSpecificationExceptionTest() {
		try {
			Utils.throwIncorrectSpecException("message 1");
			assertTrue(false);
		} catch (APIException ex) {
			assertEquals("exception should be incorrect specification exception", 
					Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED, ex.statusCode);
			assertEquals("message should be correct", 
					"message 1", ex.userFriendlyMessage);
		}
    }
	
	@Test 
	public void throwNotFoundExceptionTest() {
		try {
			Utils.throwNotFoundException("message 1");
			assertTrue(false);
		} catch (APIException ex) {
			assertEquals("exception should be incorrect specification exception", 
					Status.ERROR_RESOURCE_DOES_NOT_EXIST, ex.statusCode);
			assertEquals("message should be correct", 
					"message 1", ex.userFriendlyMessage);
		}
    }
	
	@Test
	public void ensureValidPhoneNumberTest() {
		
		//cannot be null
		try {
			Utils.ensureValidPhoneNumber(null);
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//cannot be empty string
		try {
			Utils.ensureValidPhoneNumber("");
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//should start with +
		try {
			Utils.ensureValidPhoneNumber("914422590181");
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//valid singapore number
		Utils.ensureValidPhoneNumber("+6598361844"); //no exception
		Utils.ensureValidPhoneNumber("+6593232152"); //no exception
		Utils.ensureValidPhoneNumber("+6565227030"); //no exception
		
		//india phone numbers
		Utils.ensureValidPhoneNumber("+914422593926"); //no exception
		Utils.ensureValidPhoneNumber("+919841283881"); //no exception
		Utils.ensureValidPhoneNumber("+919819532634"); //no exception
		
		//australia phone numbers
		Utils.ensureValidPhoneNumber("+61469218170"); //no exception	
		
		//US phone number
		Utils.ensureValidPhoneNumber("+19198894985"); //no exception
	}
	
	@Test
	public void ensureValidEmailTest() {
		
		//cannot be null
		try {
			Utils.ensureValidEmail(null);
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//cannot be empty string
		try {
			Utils.ensureValidEmail("");
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//cannot have special char
		try {
			Utils.ensureValidEmail("@@@sathya.com");
			assertTrue(false);
		} catch (APIException ex) {
			assertTrue(ex.statusCode == Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED);
		}
		
		//valid email addresses
		Utils.ensureValidEmail("123@sathya.com");
		Utils.ensureValidEmail("sathya.t@ishafoundation.org");
		Utils.ensureValidEmail("ramya.c@ishafoundation.org");	
	}
	
	@Test
	public void isFormatInYYYYMMDD() {
		assertEquals(false, Utils.isFormatInYYYYMMDD(2));
		assertEquals(false, Utils.isFormatInYYYYMMDD(290394938));
		assertEquals(false, Utils.isFormatInYYYYMMDD(2013312));
		assertEquals(false, Utils.isFormatInYYYYMMDD(20130229));
		assertEquals(false, Utils.isFormatInYYYYMMDD(19000229));
		assertEquals(false, Utils.isFormatInYYYYMMDD(21000229));
	
		assertEquals(true, Utils.isFormatInYYYYMMDD(20140201));
		assertEquals(true, Utils.isFormatInYYYYMMDD(20140131));
		assertEquals(true, Utils.isFormatInYYYYMMDD(20131231));
		assertEquals(true, Utils.isFormatInYYYYMMDD(20140630));	
	}
	
	@Test
	public void getDurationAsString() {
		int start;
		int end;
		
		//same start and end date
		start = 20130201;
		end = 20130201;		
		assertEquals("1 Feb 13", Utils.getDurationAsString(start, end));
		
		//same month and year
		start = 20130201;
		end = 20130204;		
		assertEquals("1 - 4 Feb 13", Utils.getDurationAsString(start, end));
		
		//different month same year
		start = 20130227;
		end = 20130304;		
		assertEquals("27 Feb - 4 Mar 13", Utils.getDurationAsString(start, end));
		
		//different year
		start = 20131227;
		end = 20140104;		
		assertEquals("27 Dec - 4 Jan 14", Utils.getDurationAsString(start, end));	
		
		start = 2013123;
		end = 2013125;
		try {
			Utils.getDurationAsString(start, end);
			assertTrue(false);
		} catch (APIException ex) {
			assertEquals(Status.ERROR_RESOURCE_INCORRECTLY_SPECIFIED, ex.statusCode);
		}
	}
	
	@Test
	public void isValidPhoneNumberTest() {
		assertTrue(false);
	}
	
	@Test public void closeEnoughTest() {
		assertFalse(Utils.closeEnough(null, null));
		
		assertTrue(Utils.closeEnough("sathya", "sathya"));
		assertTrue(Utils.closeEnough("sathya", "sathyan"));
		assertTrue(Utils.closeEnough("sathya", "sathyanarayanan"));
		assertTrue(Utils.closeEnough("radhika", "radikaa"));
		assertTrue(Utils.closeEnough("thulasi", "tulasi"));
		
		assertFalse(Utils.closeEnough("sathya", "sowmya"));
		assertFalse(Utils.closeEnough("paramesh", "giridhar"));
		assertFalse(Utils.closeEnough("giridhar", "raadhika"));
		assertFalse(Utils.closeEnough("thulasidhar", "giridhar"));
		assertFalse(Utils.closeEnough("ramesh", "suresh"));		
		assertFalse(Utils.closeEnough("sathya", "syamala"));		
	}
	
	@Test public void geDateDiffTest() {
		assertEquals("5 seconds", Utils.getDateDiff(0, 5));
		assertEquals("1 minute(s)", Utils.getDateDiff(0, 65));
		assertEquals("2 minute(s)", Utils.getDateDiff(0, 110));
		assertEquals("30 minute(s)", Utils.getDateDiff(0, 1820));
		assertEquals("1 hour(s)", Utils.getDateDiff(0, 3800));
		assertEquals("3 hour(s)", Utils.getDateDiff(0, 11000));
		
		assertEquals("1 day(s)", Utils.getDateDiff(0, 3600 * 24));
		assertEquals("2 day(s)", Utils.getDateDiff(0, 3600 * 24 * 2 + 1200));
	}
}
